#import "RepositoryProvider.h"
#import "SearchService.h"
#import <objc/runtime.h>

@interface RepositoryProvider()
@property (nonatomic, strong) SearchService* searchService;
@property (nonatomic, strong) NSMutableDictionary* repositories;
@end

@implementation RepositoryProvider

@synthesize searchService;
@synthesize repositories = _repositories;

-(NSMutableDictionary*)repositories {
    if (!_repositories) {
        _repositories = [NSMutableDictionary dictionary];
    }
    return _repositories;
}

+(NSString*)getClassName:(Class)class {
    return [NSString stringWithCString:class_getName(class) encoding:NSUTF8StringEncoding];
}

-(void)registerRepositoryForClass:(Class)class modelName:(NSString*)modelName getModelsSelector:(SEL)getModelsSelector getInfoSelector:(SEL)getInfoSelector convertFromDictionary:(ConvertFromDictionary)convertFromDictionary {
    Repository* repository = [Repository repositoryWithSearchService:self.searchService
                                                           modelName:modelName
                                                   getModelsSelector:getModelsSelector
                                                     getInfoSelector:getInfoSelector
                                               convertFromDictionary:convertFromDictionary];
    [self.repositories setObject:repository forKey:[RepositoryProvider getClassName:class]];    
}

-(void)registerRepositories {
    [self registerRepositoryForClass:[Cliente class] 
                           modelName:@"Cliente"
                   getModelsSelector:@selector(getClientes:) 
                     getInfoSelector:@selector(getClienteInfoById:error:)
               convertFromDictionary:^id<SelectableModel>(NSDictionary* dictionary){
                   return [Cliente fromDictionary:dictionary];
               }];
    [self registerRepositoryForClass:[Fabrica class] 
                           modelName:@"Fabrica"
                   getModelsSelector:@selector(getFabricas:) 
                     getInfoSelector:@selector(getFabricaInfoById:error:)
               convertFromDictionary:^id<SelectableModel>(NSDictionary* dictionary){
                   return [Fabrica fromDictionary:dictionary];
               }];
    [self registerRepositoryForClass:[Vendedor class] 
                           modelName:@"Vendedor"
                   getModelsSelector:@selector(getVendedores:) 
                     getInfoSelector:@selector(getVendedorInfoById:error:)
               convertFromDictionary:^id<SelectableModel>(NSDictionary* dictionary){
                   return [Vendedor fromDictionary:dictionary];
               }];
    [self registerRepositoryForClass:[Transportadora class] 
                           modelName:@"Transportadora"
                   getModelsSelector:@selector(getTransportadoras:) 
                     getInfoSelector:@selector(getTransportadoraInfoById:error:)
               convertFromDictionary:^id<SelectableModel>(NSDictionary* dictionary){
                   return [Transportadora fromDictionary:dictionary];
               }];
}

-(id)initWithSettings:(Settings *)settings {
    self = [super init];
    if (self) {
        self.searchService = [SearchService searchServiceWithSettings:settings];
        [self registerRepositories];
    }
    return self;
}

+(RepositoryProvider*)repositoryProviderWithSettings:(Settings *)settings {
    return [[RepositoryProvider alloc] initWithSettings:settings];
}

-(Repository*)getRepositoryForClass:(Class)class {
    return [self.repositories objectForKey:[RepositoryProvider getClassName:class]];
}

@end
